package nckd.wnqjt.tmc.tda.plugin.form;

import com.alibaba.fastjson.JSONObject;
import kd.bos.algo.*;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterItemInfo;
import kd.bos.entity.report.ReportColumn;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Classname BankAcceptanceQueryPlugin
 * @Description 银行承兑汇票进度表
 * @Version 1.0.0
 * @Date 2024/11/15 上午10:50
 * @Created by xiaoxiaopeng
 */
public class BankAcceptanceQueryPlugin extends AbstractReportListDataPlugin {
    private static Log log = LogFactory.getLog(BankAcceptanceQueryPlugin.class);

    @Override
    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {

        //取查询字段
        List<String> filedList = new ArrayList<>();
        List<ReportColumn> fileds = (List<ReportColumn>) reportQueryParam.getCustomParam().get("fileds");
        fileds.forEach(item -> {
            filedList.add(item.getFieldKey());
        });

        //过滤条件
        List<QFilter> filters = new ArrayList<>();
        List<FilterItemInfo> filterItems = reportQueryParam.getFilter().getFilterItems();
        for (FilterItemInfo item : filterItems) {
            if ("nckd_orgf".equals(item.getPropName()) && item.getValue() != null) {
                //DynamicObject org = (DynamicObject) item.getValue();
                //filters.add(new QFilter("drawercompany.id", QCP.equals, org.getPkValue()));
                Object value = item.getValue();
                DynamicObjectCollection nckdOrg = null;
                if (value != null) {
                    nckdOrg = (DynamicObjectCollection) value;
                    List<Long> longList = nckdOrg.stream().map(e -> e.getLong("id")).collect(Collectors.toList());
                    QFilter orgFilter = new QFilter("drawercompany.id", QCP.in, longList);
                    filters.add(orgFilter);
                }
            }
        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = format.parse(format.format(new Date()));

        //单据状态=已审核
        QFilter statusFilter = new QFilter("billstatus", QCP.equals, "C");
        //取票据状态=已登记
        QFilter draftFilter = new QFilter("draftbillstatus", QCP.equals, "registered");
        //票据到期日大于当前日期
        QFilter expireDateFilter = new QFilter("draftbillexpiredate", QCP.large_than, date);
        //开票
        QFilter rpTypeFilter = new QFilter("rptype", QCP.equals, "paybill");
        //承兑日期大于等于当前月份
        //QFilter acceptDateFilter = new QFilter("acceptdate", QCP.large_equals,DateUtils.getNowMonthMinToDate());


        filters.add(statusFilter);
        filters.add(draftFilter);
        filters.add(expireDateFilter);
        filters.add(rpTypeFilter);
        //filters.add(acceptDateFilter);

        //查询开票登记
        String filed = "id,billno,billstatus,draftbillstatus,draftbillexpiredate,drawercompany.id,drawercompany.name as nckd_org,drawerbankname as nckd_bank,amount as nckd_repayamount,acceptdate";
        DataSet payDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cdm_payablebill", filed, filters.toArray(new QFilter[filters.size()]), null);

        DynamicObject test = BusinessDataServiceHelper.newDynamicObject("nckd_testdocuments");
        test.set("billno","test-chengdui-" + new SimpleDateFormat("yyyyMMddHHmm").format(new Date()));
        test.set("billstatus","A");
        DynamicObjectCollection entryentity = test.getDynamicObjectCollection("entryentity");

        DataSet copyPayDataSet = payDataSet.copy();
        while (copyPayDataSet.hasNext()) {
            Row row = copyPayDataSet.next();
            DynamicObject entry = entryentity.addNew();
            entry.set("nckd_name", "开票登记");
            entry.set("nckd_number", row.get("billno"));
            entry.set("nckd_amount", row.get("nckd_repayamount"));
        }
        SaveServiceHelper.save(new DynamicObject[]{test});

        /**
         * 提取数据
         */
        Map<String, List<Map<String, Object>>> billMap = new HashMap<>();
        Iterator<Row> iterator = payDataSet.copy().iterator();
        while (iterator.hasNext()) {
            Row row = iterator.next();
            String orgName = row.getString("nckd_org");
            String bankName = row.getString("nckd_bank");
            String key = orgName + bankName;
            if (!billMap.containsKey(key)) {
                Map<String, Object> map = new HashMap<>();
                List<Map<String, Object>> list = new ArrayList<>();
                map.put("nckd_org", orgName);
                map.put("nckd_bank", bankName);
                map.put("nckd_repayamount", row.get("nckd_repayamount"));
                map.put("acceptdate", row.get("draftbillexpiredate"));
                list.add(map);
                billMap.put(key, list);
            } else {
                List<Map<String, Object>> oldList = billMap.get(key);
                Map<String, Object> map = new HashMap<>();
                map.put("nckd_org", orgName);
                map.put("nckd_bank", bankName);
                map.put("nckd_repayamount", row.get("nckd_repayamount"));
                map.put("acceptdate", row.get("draftbillexpiredate"));
                oldList.add(map);
            }
        }

        log.info("银行承兑map"+ JSONObject.toJSONString(billMap));

        List<DataType> dataTypes = new ArrayList<>();
        for (int i = 0; i < filedList.size(); i++) {
            if (i <= 1) {
                dataTypes.add(DataType.StringType);
            } else {
                dataTypes.add(DataType.BigDecimalType);
            }
        }

        //构建空的dataSet
        RowMeta createRowMeta = RowMetaFactory.createRowMeta(filedList.toArray(filedList.toArray(new String[filedList.size()])), dataTypes.toArray(dataTypes.toArray(new DataType[dataTypes.size()])));
        DataSetBuilder dataSetBuilder = Algo.create(this.getClass().getName()).createDataSetBuilder(createRowMeta);

        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("yyyyMM");
        String nowYear = yearFormat.format(new Date());

        for (Map.Entry<String, List<Map<String, Object>>> entry : billMap.entrySet()) {
            List<Map<String, Object>> rows = entry.getValue();
            Object[] row = new Object[filedList.size()];
            String[] yearFiled = {"", ""};//本年字段标识
            BigDecimal[] yearAmount = {BigDecimal.ZERO, BigDecimal.ZERO};
            List<String> newFiledList = filedList.stream().filter(f -> f.contains("month")).collect(Collectors.toList());
            String[] monthFiled = newFiledList.toArray(new String[newFiledList.size()]);
            BigDecimal[] monthAmount = new BigDecimal[newFiledList.size()];
            for (int i = 0; i < monthAmount.length; i++) {
                monthAmount[i] = BigDecimal.ZERO;
            }
            rows.forEach(t -> {
                Date acceptdate = (Date) t.get("acceptdate");
                String month = monthFormat.format(acceptdate);//日期年月
                Arrays.asList(createRowMeta.getFieldNames()).forEach(f -> {
                    if (("year" + nowYear).equals(f)) {
                        yearFiled[0] = f;
                    }
                    if (("year" + ((Integer.parseInt(nowYear)) + 1)).equals(f)) {
                        yearFiled[1] = f;
                    }
                    BigDecimal enotrepayamount = (BigDecimal) t.get("nckd_repayamount");
                    if (("month" + month).equals(f)) {
                        if (f.contains(nowYear)) {
                            yearAmount[0] = yearAmount[0].add(enotrepayamount);
                        }
                        String year1 = String.valueOf((Integer.parseInt(nowYear) + 1));
                        if (f.contains(year1)) {
                            yearAmount[1] = yearAmount[1].add(enotrepayamount);
                        }
                        Arrays.asList(monthFiled).forEach(m->{
                            if (f.equals(m)) {
                                int i = Arrays.asList(monthFiled).indexOf(m);
                                monthAmount[i] = monthAmount[i].add(enotrepayamount);
                            }
                        });
                        //row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(f)] = enotrepayamount;
                    }
                });
            });
            row[0] = rows.get(0).get("nckd_org");//单元
            row[1] = rows.get(0).get("nckd_bank");//金融机构
            row[2] = (yearAmount[0].add(yearAmount[1])).divide(new BigDecimal(10000));//金额
            Arrays.asList(createRowMeta.getFieldNames()).forEach(f->{
                if (f.contains("month")) {
                    int i = newFiledList.indexOf(f);
                    row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(f)] = monthAmount[i].divide(new BigDecimal(10000));
                }
            });

            if (StringUtils.isNotEmpty(yearFiled[0])) {
                row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(yearFiled[0])] = yearAmount[0].divide(new BigDecimal(10000));
            }
            if (StringUtils.isNotEmpty(yearFiled[1])) {
                row[Arrays.asList(createRowMeta.getFieldNames()).indexOf(yearFiled[1])] = yearAmount[1].divide(new BigDecimal(10000));
            }
            dataSetBuilder.append(row);
        }
        //根据公司排序
        DataSet bnakLoanDataSet = dataSetBuilder.build().orderBy(new String[]{"nckd_org"});
        DataSet copy = bnakLoanDataSet.copy();
        StringBuffer bankLog = new StringBuffer();
        while (copy.hasNext()) {
            Row row = copy.next();
            bankLog.append(row.get("nckd_org")).append("-").append(row.get("nckd_bank")).append(",\n");
        }
        log.info("银行承兑汇票返回结果",bankLog.toString());


        bnakLoanDataSet = bnakLoanDataSet.addField("1","count");
        //合计字段
        GroupbyDataSet sumGroup = bnakLoanDataSet.copy().groupBy(new String[]{"nckd_org"});
        //公司合计行标识
        String sumFiled = "nckd_org,concat('小计') as nckd_bank";
        for (int i = 2; i < filedList.size(); i++) {
            sumFiled = sumFiled + "," + filedList.get(i);
            sumGroup = sumGroup.sum(filedList.get(i));
        }
        DataSet orgCountDataSet = sumGroup.finish();
        //新增公司合计行
        orgCountDataSet = orgCountDataSet.select(sumFiled).addField("2","count");
        /**
         *  增加总计行
         */
        GroupbyDataSet totalGroup = orgCountDataSet.copy().groupBy(new String[]{"nckd_bank"});
        //总计行标识
        String totalFiled = "concat('合计') as nckd_org,'-' as nckd_bank";
        for (int i = 2; i < filedList.size(); i++) {
            totalFiled = totalFiled + "," + filedList.get(i);
            totalGroup = totalGroup.sum(filedList.get(i));
        }
        DataSet totalDataSet = totalGroup.finish();
        totalDataSet = totalDataSet.select(totalFiled).addField("3","count").addField("2","totalCount");

        DataSet resultDataSet = bnakLoanDataSet.union(orgCountDataSet);
        resultDataSet = resultDataSet.addField("1","totalCount");
        resultDataSet = resultDataSet.union(totalDataSet).orderBy(new String[]{"nckd_org", "count"}).orderBy(new String[]{"totalCount"});

        return resultDataSet;
    }
}
